home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / PROGRAMM / DB_CLIPP / 2510.ZIP / TRSOURCE.EXE / ARRSAVE.C < prev    next >
C/C++ Source or Header  |  1990-10-22  |  7KB  |  209 lines

  1. /*********
  2. *  ARRSAVE
  3. *
  4. *  by Leonard Zerman
  5. *  modified by Tom Rettig
  6. *
  7. * Placed in the public domain by Tom Rettig Associates, 10/22/1990.
  8. *
  9. *  Syntax: ARRSAVE(<filename>, <array>)
  10. *  Return: True if succesful else false.
  11. *  Note  : This version will save all the array elements 
  12. *          of all data types to a file.
  13. *          Undefined type becomes logical .F.
  14. *          Only single dimension arrays are supported.
  15. *          The file contains a header of the format:
  16. * ------------------------------------------------------------------------
  17. * |Header len|# of items|Largest|chksum|Type table|Len    |Position|Items|
  18. * |int       |int       |int    |int   |char * N  |int * N|long * N|N * N|
  19. * -------------------------------------------------------------------------
  20. *********/
  21.  
  22. #include "trlib.h"
  23.  
  24. #define DATESTRLEN 9                /* 8 bytes + NULL = 9 */
  25. #define SEEK_SET   0
  26. #define UNDEFINED  0
  27. #define MAXFNAMELEN 65
  28.  
  29. typedef union                       /* union will handle all data types */
  30. {
  31.    char * ptr;                      /* ptr for string or date */
  32.    int    log;                      /* int for logical */
  33.    double num;                      /* double for numerics */
  34. }DATA;
  35.  
  36. typedef struct
  37. {
  38.    int  datatype;
  39.    int  datalen;
  40.    char datachar;
  41.    void * vptr;
  42.    DATA data;
  43. }DATAINFO;
  44.  
  45. typedef struct
  46. {
  47.    int headerlen;
  48.    int nbr_of_items;
  49.    int largest;
  50.    int chksum;
  51. }ARRAYHEAD;
  52.  
  53. typedef struct
  54. {
  55.    ARRAYHEAD head;
  56.    char * typetable;                      /* pointer to allocated tables */
  57.    int  * lentable;
  58.    long * postable;
  59.    char * buffer;
  60.    int  typetablesize;
  61.    int  lentablesize;
  62.    int  postablesize;
  63.    int  buffersize;
  64.    int  fhandle;
  65.    long curpos;
  66. }ARRAYTABLE;
  67.  
  68. void far * _xalloc(unsigned int size);
  69. void _xfree(void far *mem);
  70.  
  71. /*-------------------------------------------------------------------------*/
  72.  
  73. TRTYPE ARRSAVE() 
  74. {
  75.    static char fnamebuff[MAXFNAMELEN];
  76.    int i;
  77.    int len;
  78.    int retval;
  79.    char * fname;
  80.    DATAINFO  item;
  81.    ARRAYTABLE arraytable;
  82.  
  83.    retval               = FALSE;
  84.    arraytable.typetable = (char *)0;
  85.    arraytable.lentable  = (int *) 0;
  86.    arraytable.postable  = (long *)0;
  87.    arraytable.fhandle   = ERRORNEG;
  88.  
  89.    if(PCOUNT == 2 && ISCHAR(1) && ISARRAY(2)) 
  90.    {  
  91.       fname = _parc(1);
  92.       if((arraytable.head.nbr_of_items = ALENGTH(2)) < 1) 
  93.          goto ERROREXIT;
  94.  
  95.       fname = _tr_strcpy(fnamebuff, fname);
  96.       if(!_tr_stpchr(fname, '.'))
  97.          _tr_strcat(fname, ".ARR");
  98.  
  99.       if((arraytable.fhandle = _tr_creat(fname, FL_NORMAL)) 
  100.           == ERRORNEG)
  101.          goto ERROREXIT;
  102. /*-------------------------------------------------------------------------*/
  103.       arraytable.typetablesize = sizeof(char) * arraytable.head.nbr_of_items;
  104.       arraytable.lentablesize  = sizeof(int)  * arraytable.head.nbr_of_items;
  105.       arraytable.postablesize  = sizeof(long) * arraytable.head.nbr_of_items;
  106.  
  107.       /* allocate tables */
  108.       if((arraytable.typetable = (char *)_xalloc(arraytable.typetablesize)) == (char *)0)
  109.          goto ERROREXIT;
  110.       if((arraytable.lentable  = (int *)_xalloc(arraytable.lentablesize)) == (int *)0)
  111.          goto ERROREXIT;
  112.       if((arraytable.postable  = (long *)_xalloc(arraytable.postablesize)) == (long *)0)
  113.          goto ERROREXIT;
  114.  
  115. /*-------------------------------------------------------------------------*/
  116.       arraytable.head.largest   = 0;
  117.       arraytable.head.headerlen = sizeof(arraytable.head)  + 
  118.                                   arraytable.typetablesize + 
  119.                                   arraytable.lentablesize  + 
  120.                                   arraytable.postablesize;
  121.  
  122.       if((arraytable.curpos =_tr_lseek(arraytable.fhandle,
  123.          (long)arraytable.head.headerlen, SEEK_SET)) == ERRORNEGL)
  124.          goto ERROREXIT;
  125. /*-------------------------------------------------------------------------*/
  126.       for(i = 1; i <= arraytable.head.nbr_of_items; i++)
  127.       {
  128.          item.datatype = _parinfa(2,i) & 0x000F; /* find out what data type */
  129.  
  130.          switch(item.datatype)
  131.          {
  132.             case CHARACTER:
  133.                item.data.ptr = _parc(2,i);  /* assign char * */
  134.                item.vptr     = item.data.ptr;
  135.                item.datalen  = _parclen(2,i) + 1;
  136.                if(item.datalen == strlen(item.data.ptr) + 1)
  137.                   item.datachar = 'C';
  138.                else
  139.                   item.datachar = 'B';
  140.                break;
  141.             case NUMERIC:
  142.                item.data.num = _parnd(2,i); /* assign double */
  143.                item.vptr     = &item.data.num;
  144.                item.datalen  = sizeof(double);
  145.                item.datachar = 'N';
  146.                break;
  147.             case LOGICAL:
  148.                item.data.log = _parl(2,i);  /* assign logical int */
  149.                item.vptr     = &item.data.log;
  150.                item.datalen  = sizeof(int);
  151.                item.datachar = 'L';
  152.                break;
  153.             case DATE:
  154.                item.data.ptr  = _pards(2,i); /* assign char* to date string */
  155.                item.vptr      = item.data.ptr;
  156.                item.datalen   = DATESTRLEN;
  157.                item.datachar  = 'D';
  158.                break;
  159.             case UNDEFINED:
  160.             default:
  161.                item.data.log = 0;         /* assign logical int */
  162.                item.vptr     = &item.data.log;
  163.                item.datalen  = sizeof(int);
  164.                item.datachar = 'L';
  165.          } /* end switch */
  166.          arraytable.typetable[i - 1] = item.datachar;
  167.          arraytable.lentable[i - 1]  = item.datalen;
  168.          arraytable.postable[i - 1]  = arraytable.curpos;
  169.          arraytable.curpos += item.datalen;
  170.  
  171.          if(item.datalen > arraytable.head.largest)
  172.             arraytable.head.largest = item.datalen;
  173.  
  174.          if(_tr_write(arraytable.fhandle, item.vptr, item.datalen) != 
  175.                       item.datalen)
  176.             goto ERROREXIT;
  177.       } /* end of for-loop */
  178. /*-------------------------------------------------------------------------*/
  179.       arraytable.head.chksum = arraytable.head.headerlen    +
  180.                                arraytable.head.nbr_of_items + 
  181.                                arraytable.head.largest;
  182.       /* write header */
  183.       if(_tr_lseek(arraytable.fhandle,0L,SEEK_SET) == ERRORNEGL)
  184.          goto ERROREXIT;
  185.       if(_tr_write(arraytable.fhandle, &arraytable.head,
  186.                    sizeof(arraytable.head)) != sizeof(arraytable.head))
  187.          goto ERROREXIT;
  188.       if(_tr_write(arraytable.fhandle, arraytable.typetable,
  189.                    arraytable.typetablesize) != arraytable.typetablesize)
  190.          goto ERROREXIT;
  191.       if(_tr_write(arraytable.fhandle, arraytable.lentable,
  192.                    arraytable.lentablesize) != arraytable.lentablesize)
  193.          goto ERROREXIT;
  194.       if(_tr_write(arraytable.fhandle, arraytable.postable,
  195.                    arraytable.postablesize) != arraytable.postablesize)
  196.          goto ERROREXIT;
  197.  
  198.       retval = TRUE;
  199. ERROREXIT:
  200.       if(arraytable.fhandle != ERRORNEG)
  201.          _tr_close(arraytable.fhandle);
  202.       _xfree(arraytable.typetable);
  203.       _xfree(arraytable.lentable);
  204.       _xfree(arraytable.postable);
  205.    }
  206.    _retl(retval);
  207. }
  208. /*-------------------------------------------------------------------------*/
  209.